﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="BaseModelTests.cs" company="XamlNinja">
//   2011 Richard Griffin and Ollie Riches
// </copyright>
// <summary>
//   Observable collection unit tests - we follow BDD principles, http://dannorth.net/introducing-bdd/
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace WP7Contrib.Common.Tests
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using Microsoft.Silverlight.Testing;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Models;

    [TestClass]
    public class BaseModelTests : SilverlightTest
    {
        [TestMethod]
        public void ShouldRaiseEventWhenItemPropertyChanged()
        {
            // Given we have an observable model...
            var model = new SimpleModel(string.Empty, 0);

            // Given we observe property changed events...
            var events = new List<PropertyChangedEventArgs>();
            model.PropertyChanged += (sender, args) => events.Add(args);

            // When we change the properties...
            model.RaisePropertyChangedEventsUsingExpressionSyntax();
            model.RaisePropertyChangedEventsUsingPropertyNameSyntax();

            // Then we expect 4 events to have fired, 2 for each property...
            Assert.IsTrue(events.Count == 4);
            Assert.IsTrue(events.Where(e => e.PropertyName == "StringValue").Count() == 2);
            Assert.IsTrue(events.Where(e => e.PropertyName == "DoubleValue").Count() == 2);
        }

        [TestMethod]
        public void ShouldNotRaiseEventWhenPropertyIsTheSame()
        {
            // Given we have an observable model...
            var model = new SimpleModel(string.Empty, 0);

            // Given we observe property changed events...
            var events = new List<PropertyChangedEventArgs>();
            model.PropertyChanged += (sender, args) => events.Add(args);

            // Given we change the property for a first time...
            model.DoubleValue = 42;

            // When we change the property for a second time to the same value...
            model.DoubleValue = 42;

            // Then we expect to receive only 1 event...
            Assert.IsTrue(events.Count == 1);
            Assert.IsNotNull(events.Select(e => e.PropertyName == "StringValue").First());
        }

        [TestMethod]
        public void ShouldCalculateMatchingHashCodes()
        {
            // Given we have an observable models...
            var model1 = new SimpleModel(string.Empty, 42);
            var model2 = new SimpleModel(string.Empty, 42); 

            // When we get hash codes...
            var hashCode1 = model1.GetHashCode();
            var hashCode2 = model2.GetHashCode();

            // Then we expect the hash codes to be the same...
            Assert.IsTrue(hashCode1 == hashCode2);
            Assert.AreEqual(model1, model2);
        }

        [TestMethod]
        public void ShouldCalculateDifferentHashCodes()
        {
            // Given we have an observable models...
            var model1 = new SimpleModel(Guid.NewGuid().ToString(), 42);
            var model2 = new SimpleModel(Guid.NewGuid().ToString(), 42);

            // When we get hash codes...
            var hashCode1 = model1.GetHashCode();
            var hashCode2 = model2.GetHashCode();

            // Then we expect the hash codes to be the same...
            Assert.IsFalse(hashCode1 == hashCode2);
            Assert.AreNotEqual(model1, model2);
        }
    }
}
